package controller;

import java.net.InetAddress;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

import javax.swing.DefaultListModel;

import network.LocalNetworkSettings;

public class ContactsTable {

	private static ContactsTable instance = null;
	
	private ConcurrentHashMap<InetAddress, Contact> mapContacts;
	
	private static String localUsername = null;	
	
	private static DefaultListModel modelGUI = null;
	
	private ContactsTable() {
		mapContacts = new ConcurrentHashMap<InetAddress, Contact>(20);
	}

	public static ContactsTable getInstance()
	{
		if(instance == null)
			instance = new ContactsTable();
		
		return instance;
	}
	
	public static void setLocalUsername(String username)
	{
		localUsername = username;
	}
	
	public static String getLocalUsername()
	{
		return localUsername;
	}
	
	public static void setModel(DefaultListModel model)
	{
		modelGUI = model;
	}
	
	public String getLocalusername()
	{
		return localUsername;
	}
	
	public void add(Contact contact)
	{
		mapContacts.putIfAbsent(contact.getIpAddr(), contact);
		modelGUI.addElement(contact);//.username + "@" + contact.getIpAddr().getHostAddress());
	}
	
	public void remove(Contact contact)
	{
		mapContacts.remove(contact.getIpAddr());
		modelGUI.removeElement(contact);//.username + "@" + contact.getIpAddr().getHostAddress());
	}
	
	public void remove(InetAddress ipAddr)
	{
		Contact contact = mapContacts.remove(ipAddr);
		modelGUI.removeElement(contact);//.username + "@" + contact.getIpAddr().getHostAddress());
	}
	
	public Contact get(InetAddress ipAddr)
	{
		return mapContacts.get(ipAddr);
	}
	
	public boolean isEmpty()
	{
		return mapContacts.isEmpty();
	}
	
	public int getSize()
	{
		return mapContacts.size();
	}
	
	public boolean present(InetAddress ipAddr)
	{
		return mapContacts.containsKey(ipAddr);
	}
	
	public void update(InetAddress ipAddr, Date newHeartBeatTime)
	{
		Contact c = mapContacts.remove(ipAddr);
		
		if(c != null)
		{
			c.updateHeartBeat(newHeartBeatTime);
			mapContacts.putIfAbsent(c.getIpAddr(), c);
		}
	}
	
	public void removeOutDated()
	{
		Date currentTime = new Date();
		
		for (InetAddress mapKey : mapContacts.keySet()) {
			if( mapContacts.get(mapKey).getLastHeartBeat().getTime() + LocalNetworkSettings.LIFETIME < currentTime.getTime() )
				remove(mapKey);
		}
	}
	
	public void clear()
	{
		mapContacts.clear();
		modelGUI.clear();
	}
}